package com.vimi8.chick.plugins.utils

import java.text.SimpleDateFormat
import java.util.*
import java.util.regex.Pattern

/**
 * 时间、日期工具类
 */
object DateTimeUtil {

    /** 日期格式：yyyy-MM-dd HH:mm:ss  */
    val DF_YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss"

    /** 日期格式：yyyy-MM-dd HH:mm  */
    val DF_YYYY_MM_DD_HH_MM = "yyyy-MM-dd HH:mm"

    /** 日期格式：yyyy-MM-dd  */
    val DF_YYYY_MM_DD = "yyyy-MM-dd"

    /** 日期格式：HH:mm:ss  */
    val DF_HH_MM_SS = "HH:mm:ss"

    /** 日期格式：HH:mm  */
    val DF_HH_MM = "HH:mm"

    /**
     * 格式化日期，默认yyyy-MM-dd HH:mm:ss
     * @param date 日期
     * @param ft 转换类型
     */

    fun formatDateTime(date: Date, ft: String = DF_YYYY_MM_DD_HH_MM_SS): String {
        val dateFormat = SimpleDateFormat(ft, Locale.SIMPLIFIED_CHINESE)
        return try {
            dateFormat.format(date)
        } catch (e: Exception) {
            ""
        }
    }

    /**
     * 格式化日期，默认yyyy-MM-dd HH:mm:ss
     */
    fun formatDateTime(dateL: Long, ft: String = DF_YYYY_MM_DD_HH_MM_SS): String {
        return formatDateTime(Date(dateL), ft)
    }

    /**
     * 格式化日期，默认yyyy-MM-dd HH:mm:ss
     */
    fun formatDateTime(dateStr: String?, ft: String = DF_YYYY_MM_DD_HH_MM_SS): String  {
        if (dateStr == null) {
            return ""
        }
        val date = parseDate(dateStr)
        return when (date) {
            null -> ""
            else -> formatDateTime(date)
        }
    }

    /**
     * 将日期字符串转成日期
     */
    fun parseDate(dateStr: String, format: String = DF_YYYY_MM_DD_HH_MM_SS): Date? {
        val dateFormat = SimpleDateFormat(format, Locale.SIMPLIFIED_CHINESE)
        return try {
            dateFormat.isLenient = false
            dateFormat.parse(dateStr)
        } catch (e: Exception) {
            null
        }
    }

    /**
     * 格式化当前日期
     */
    fun formatCurrentDateTime(format: String = DF_YYYY_MM_DD_HH_MM_SS): String {
        return formatDateTime(Calendar.getInstance().time, format)
    }

    /**
     * 获取某年某月的天数
     *
     * @param year
     * @param month  int 月份[1-12]
     * @return int
     */
    fun getDaysOfMonth(year: Int, month: Int): Int {
        val calendar = Calendar.getInstance()
        calendar.set(year, month - 1, 1)
        return calendar.getActualMaximum(Calendar.DAY_OF_MONTH)
    }

    /**
     * 获得当前日天
     *
     * @return int
     */
    fun getCurrentDay(): Int {
        val calendar = Calendar.getInstance()
        return calendar.get(Calendar.DATE)
    }

    /**
     * 获得当前月份
     *
     * @return int
     */
    fun getCurrentMonth(): Int {
        val calendar = Calendar.getInstance()
        return calendar.get(Calendar.MONTH) + 1
    }

    /**
     * 获得当前年份
     *
     * @return int
     */
    fun getCurrentYear(): Int {
        val calendar = Calendar.getInstance()
        return calendar.get(Calendar.YEAR)
    }

    /**
     * 获得当前时间戳Long
     *
     * @return int
     */
    fun getCurrentTime(): Long {
        val calendar = Calendar.getInstance()
        return calendar.timeInMillis
    }

    /**
     * 返回日期的天
     *
     * @param date
     * @return int
     */
    fun getDay(date: Date): Int {
        val calendar = Calendar.getInstance()
        calendar.time = date
        return calendar.get(Calendar.DATE)
    }

    /**
     * 返回日期的年
     *
     * @param date
     * @return int
     */
    fun getYear(date: Date): Int {
        val calendar = Calendar.getInstance()
        calendar.time = date
        return calendar.get(Calendar.YEAR)
    }

    /**
     * 返回日期的月份，1-12
     *
     * @param date
     * @return int
     */
    fun getMonth(date: Date): Int {
        val calendar = Calendar.getInstance()
        calendar.time = date
        return calendar.get(Calendar.MONTH) + 1
    }

    /**
     * 计算两个日期相差的天数，如果date2 > date1 返回正数，否则返回负数
     *
     * @param date1
     * @param date2
     * @return long
     */
    fun dayDiff(date1: Date, date2: Date): Long {
        return (date2.time - date1.time) / 86400000
    }

    /**
     * 获取每月的第一周
     *
     * @param year
     * @param month
     */
    fun getFirstWeekdayOfMonth(year: Int, month: Int): Int {
        val calendar = Calendar.getInstance()
        calendar.firstDayOfWeek = Calendar.SATURDAY // 星期天为第一天
        calendar.set(year, month - 1, 1)
        return calendar.get(Calendar.DAY_OF_WEEK)
    }

    /**
     * 获取每月的最后一周
     *
     * @param year
     * @param month
     */
    fun getLastWeekdayOfMonth(year: Int, month: Int): Int {
        val calendar = Calendar.getInstance()
        calendar.firstDayOfWeek = Calendar.SATURDAY // 星期天为第一天
        calendar.set(year, month - 1, getDaysOfMonth(year, month))
        return calendar.get(Calendar.DAY_OF_WEEK)
    }

    /**
     * 获取本月最后一天
     *
     * @return
     */
    fun getLastDayOfMonth(): Int {
        val calendar = Calendar.getInstance()
        calendar.set(Calendar.DATE, 1)
        calendar.add(Calendar.MONTH, 1)
        calendar.add(Calendar.DATE, -1)
        return calendar.get(Calendar.DATE)
    }

    /**
     * 判断日期是否有效,包括闰年的情况
     * @param date YYYY-mm-dd
     * @return
     */
    fun isDate(date: String): Boolean {
        val reg = StringBuffer(
                "^((\\d{2}(([02468][048])|([13579][26]))-?((((0?")
        reg.append("[13578])|(1[02]))-?((0?[1-9])|([1-2][0-9])|(3[01])))")
        reg.append("|(((0?[469])|(11))-?((0?[1-9])|([1-2][0-9])|(30)))|")
        reg.append("(0?2-?((0?[1-9])|([1-2][0-9])))))|(\\d{2}(([02468][12")
        reg.append("35679])|([13579][01345789]))-?((((0?[13578])|(1[02]))")
        reg.append("-?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))")
        reg.append("-?((0?[1-9])|([1-2][0-9])|(30)))|(0?2-?((0?[")
        reg.append("1-9])|(1[0-9])|(2[0-8]))))))")
        val p = Pattern.compile(reg.toString())
        return p.matcher(date).matches()
    }

    /**
     * 以友好方式
     */
    fun getFriendlyTime(dateString: String?): String {
        if (dateString == null) return ""
        var date = parseDate(dateString) ?: return ""

        // 时区
        val time = date.time
        if (TimeZone.getDefault() != TimeZone.getTimeZone("GMT+08:00")) {
            date = Date(time - (TimeZone.getTimeZone("GMT+08:00").getOffset(time) - TimeZone.getDefault().getOffset(time)))
        }

        val delta = (Date().time - date.time) / 1000
        return when {
            delta < 0 -> formatDateTime(date, DF_YYYY_MM_DD) // 未来
            delta < 60 -> "${delta}秒前"
            delta < 60 * 60 -> "${delta / 60}分钟前"
            delta < 60 * 60 * 24 -> "${delta / 60 / 60}小时前"
            delta < 60 * 60 * 24 * 30 -> "${delta / 60 / 60 / 24}天前"
            delta < 60 * 60 * 24 * 365 -> "${delta / 60 / 60 / 24 / 30}个月前"
            else -> "${delta / 60 / 60 / 24 / 365}年前"
        }
    }

}

